//! # 消息路由器
//!
//! 实现消息路由和过滤机制

use std::collections::HashMap;
use std::sync::Arc;
use regex::Regex;

use crate::bus::MessageFilter;
use crate::error::{MessageBusError, MessageBusResult};
use crate::message::Message;

/// 主题匹配模式
#[derive(Debug, Clone)]
pub enum TopicPattern {
    /// 精确匹配
    Exact(String),
    /// 通配符匹配（* 匹配单个级别，** 匹配多个级别）
    Wildcard(String),
    /// 正则表达式匹配
    Regex(Regex),
}

impl TopicPattern {
    /// 创建精确匹配模式
    pub fn exact(pattern: impl Into<String>) -> Self {
        TopicPattern::Exact(pattern.into())
    }

    /// 创建通配符匹配模式
    pub fn wildcard(pattern: impl Into<String>) -> Self {
        TopicPattern::Wildcard(pattern.into())
    }

    /// 创建正则表达式匹配模式
    pub fn regex(pattern: impl AsRef<str>) -> MessageBusResult<Self> {
        let regex = Regex::new(pattern.as_ref())
            .map_err(|e| MessageBusError::config_error("regex", pattern.as_ref(), e.to_string()))?;
        Ok(TopicPattern::Regex(regex))
    }

    /// 检查主题是否匹配模式
    pub fn matches(&self, topic: &str) -> bool {
        match self {
            TopicPattern::Exact(pattern) => pattern == topic,
            TopicPattern::Wildcard(pattern) => self.matches_wildcard(pattern, topic),
            TopicPattern::Regex(regex) => regex.is_match(topic),
        }
    }

    /// 通配符匹配实现
    fn matches_wildcard(&self, pattern: &str, topic: &str) -> bool {
        if pattern == "**" {
            return true; // 匹配所有
        }

        let pattern_parts: Vec<&str> = pattern.split('.').collect();
        let topic_parts: Vec<&str> = topic.split('.').collect();

        self.matches_parts(&pattern_parts, &topic_parts, 0, 0)
    }

    /// 递归匹配部分
    fn matches_parts(
        &self,
        pattern_parts: &[&str],
        topic_parts: &[&str],
        pattern_idx: usize,
        topic_idx: usize,
    ) -> bool {
        // 如果模式和主题都到达末尾，匹配成功
        if pattern_idx >= pattern_parts.len() && topic_idx >= topic_parts.len() {
            return true;
        }

        // 如果模式到达末尾但主题还有剩余，匹配失败
        if pattern_idx >= pattern_parts.len() {
            return false;
        }

        let pattern_part = pattern_parts[pattern_idx];

        if pattern_part == "**" {
            // ** 匹配零个或多个级别
            // 尝试匹配下一个模式部分
            if pattern_idx + 1 < pattern_parts.len() {
                // 尝试从当前主题位置开始匹配剩余模式
                for i in topic_idx..=topic_parts.len() {
                    if self.matches_parts(pattern_parts, topic_parts, pattern_idx + 1, i) {
                        return true;
                    }
                }
                false
            } else {
                // ** 是最后一个模式部分，匹配剩余所有主题
                true
            }
        } else if pattern_part == "*" {
            // * 匹配单个级别
            if topic_idx >= topic_parts.len() {
                return false;
            }
            self.matches_parts(pattern_parts, topic_parts, pattern_idx + 1, topic_idx + 1)
        } else {
            // 精确匹配
            if topic_idx >= topic_parts.len() || pattern_part != topic_parts[topic_idx] {
                return false;
            }
            self.matches_parts(pattern_parts, topic_parts, pattern_idx + 1, topic_idx + 1)
        }
    }

    /// 获取模式字符串
    pub fn pattern(&self) -> String {
        match self {
            TopicPattern::Exact(pattern) => pattern.clone(),
            TopicPattern::Wildcard(pattern) => pattern.clone(),
            TopicPattern::Regex(regex) => regex.as_str().to_string(),
        }
    }
}

/// 内容过滤器 - 基于消息内容进行过滤
#[derive(Debug, Clone)]
pub struct ContentFilter {
    /// 字段路径（使用点分隔，如 "user.id"）
    pub field_path: String,
    /// 期望值
    pub expected_value: serde_json::Value,
    /// 比较操作
    pub operation: ComparisonOperation,
}

/// 比较操作
#[derive(Debug, Clone)]
pub enum ComparisonOperation {
    /// 等于
    Equal,
    /// 不等于
    NotEqual,
    /// 大于
    GreaterThan,
    /// 大于等于
    GreaterThanOrEqual,
    /// 小于
    LessThan,
    /// 小于等于
    LessThanOrEqual,
    /// 包含（字符串）
    Contains,
    /// 不包含（字符串）
    NotContains,
    /// 正则匹配
    Regex(Regex),
}

impl ContentFilter {
    /// 创建等于过滤器
    pub fn equal(field_path: impl Into<String>, value: serde_json::Value) -> Self {
        Self {
            field_path: field_path.into(),
            expected_value: value,
            operation: ComparisonOperation::Equal,
        }
    }

    /// 创建包含过滤器
    pub fn contains(field_path: impl Into<String>, value: impl Into<String>) -> Self {
        Self {
            field_path: field_path.into(),
            expected_value: serde_json::Value::String(value.into()),
            operation: ComparisonOperation::Contains,
        }
    }

    /// 创建正则匹配过滤器
    pub fn regex(field_path: impl Into<String>, pattern: impl AsRef<str>) -> MessageBusResult<Self> {
        let regex = Regex::new(pattern.as_ref())
            .map_err(|e| MessageBusError::config_error("regex", pattern.as_ref(), e.to_string()))?;
        Ok(Self {
            field_path: field_path.into(),
            expected_value: serde_json::Value::Null,
            operation: ComparisonOperation::Regex(regex),
        })
    }

    /// 从消息中提取字段值
    fn extract_field_value<'a>(&self, message: &'a Message) -> Option<&'a serde_json::Value> {
        let parts: Vec<&str> = self.field_path.split('.').collect();
        let mut current = message.payload();

        for part in parts {
            current = current.get(part)?;
        }

        Some(current)
    }

    /// 比较值
    fn compare_values(&self, actual: &serde_json::Value) -> bool {
        match &self.operation {
            ComparisonOperation::Equal => actual == &self.expected_value,
            ComparisonOperation::NotEqual => actual != &self.expected_value,
            ComparisonOperation::GreaterThan => {
                if let (Some(a), Some(e)) = (actual.as_f64(), self.expected_value.as_f64()) {
                    a > e
                } else {
                    false
                }
            }
            ComparisonOperation::GreaterThanOrEqual => {
                if let (Some(a), Some(e)) = (actual.as_f64(), self.expected_value.as_f64()) {
                    a >= e
                } else {
                    false
                }
            }
            ComparisonOperation::LessThan => {
                if let (Some(a), Some(e)) = (actual.as_f64(), self.expected_value.as_f64()) {
                    a < e
                } else {
                    false
                }
            }
            ComparisonOperation::LessThanOrEqual => {
                if let (Some(a), Some(e)) = (actual.as_f64(), self.expected_value.as_f64()) {
                    a <= e
                } else {
                    false
                }
            }
            ComparisonOperation::Contains => {
                if let (Some(a), Some(e)) = (actual.as_str(), self.expected_value.as_str()) {
                    a.contains(e)
                } else {
                    false
                }
            }
            ComparisonOperation::NotContains => {
                if let (Some(a), Some(e)) = (actual.as_str(), self.expected_value.as_str()) {
                    !a.contains(e)
                } else {
                    false
                }
            }
            ComparisonOperation::Regex(regex) => {
                if let Some(s) = actual.as_str() {
                    regex.is_match(s)
                } else {
                    false
                }
            }
        }
    }
}

impl MessageFilter for ContentFilter {
    fn matches(&self, message: &Message) -> bool {
        if let Some(actual_value) = self.extract_field_value(message) {
            self.compare_values(actual_value)
        } else {
            false
        }
    }

    fn description(&self) -> String {
        format!("ContentFilter({})", self.field_path)
    }
}

/// 组合过滤器 - 支持多个过滤器的逻辑组合
pub struct CompositeFilter {
    filters: Vec<Box<dyn MessageFilter>>,
    operation: LogicalOperation,
}

/// 逻辑操作
#[derive(Debug, Clone, PartialEq)]
pub enum LogicalOperation {
    /// 与操作（所有过滤器都匹配）
    And,
    /// 或操作（任一过滤器匹配）
    Or,
    /// 非操作（不匹配）
    Not,
}

impl CompositeFilter {
    /// 创建与操作过滤器
    pub fn and(filters: Vec<Box<dyn MessageFilter>>) -> Self {
        Self {
            filters,
            operation: LogicalOperation::And,
        }
    }

    /// 创建或操作过滤器
    pub fn or(filters: Vec<Box<dyn MessageFilter>>) -> Self {
        Self {
            filters,
            operation: LogicalOperation::Or,
        }
    }

    /// 创建非操作过滤器
    pub fn not(filter: Box<dyn MessageFilter>) -> Self {
        Self {
            filters: vec![filter],
            operation: LogicalOperation::Not,
        }
    }
}

impl MessageFilter for CompositeFilter {
    fn matches(&self, message: &Message) -> bool {
        match self.operation {
            LogicalOperation::And => self.filters.iter().all(|f| f.matches(message)),
            LogicalOperation::Or => self.filters.iter().any(|f| f.matches(message)),
            LogicalOperation::Not => {
                if let Some(filter) = self.filters.first() {
                    !filter.matches(message)
                } else {
                    false
                }
            }
        }
    }

    fn description(&self) -> String {
        let filter_descriptions: Vec<String> = self.filters.iter()
            .map(|f| f.description())
            .collect();
        format!("CompositeFilter({:?}: [{}])", self.operation, filter_descriptions.join(", "))
    }
}

/// 消息路由器
pub struct MessageRouter {
    /// 路由规则
    routes: HashMap<String, RouteInfo>,
    /// 默认过滤器
    default_filters: Vec<Box<dyn MessageFilter>>,
}

/// 路由信息
struct RouteInfo {
    /// 主题模式
    pattern: TopicPattern,
    /// 过滤器列表
    filters: Vec<Box<dyn MessageFilter>>,
    /// 目标订阅者 ID 列表
    subscriber_ids: Vec<String>,
}

impl MessageRouter {
    /// 创建新的消息路由器
    pub fn new() -> Self {
        Self {
            routes: HashMap::new(),
            default_filters: Vec::new(),
        }
    }

    /// 添加路由规则
    pub fn add_route(
        &mut self,
        route_id: impl Into<String>,
        pattern: TopicPattern,
        filters: Vec<Box<dyn MessageFilter>>,
    ) {
        let route_info = RouteInfo {
            pattern,
            filters,
            subscriber_ids: Vec::new(),
        };
        self.routes.insert(route_id.into(), route_info);
    }

    /// 添加订阅者到路由
    pub fn add_subscriber_to_route(
        &mut self,
        route_id: &str,
        subscriber_id: impl Into<String>,
    ) -> MessageBusResult<()> {
        if let Some(route) = self.routes.get_mut(route_id) {
            route.subscriber_ids.push(subscriber_id.into());
            Ok(())
        } else {
            Err(MessageBusError::routing_error(
                route_id,
                "路由不存在",
            ))
        }
    }

    /// 从路由中移除订阅者
    pub fn remove_subscriber_from_route(
        &mut self,
        route_id: &str,
        subscriber_id: &str,
    ) -> MessageBusResult<()> {
        if let Some(route) = self.routes.get_mut(route_id) {
            route.subscriber_ids.retain(|id| id != subscriber_id);
            Ok(())
        } else {
            Err(MessageBusError::routing_error(
                route_id,
                "路由不存在",
            ))
        }
    }

    /// 移除路由规则
    pub fn remove_route(&mut self, route_id: &str) -> MessageBusResult<()> {
        if self.routes.remove(route_id).is_some() {
            Ok(())
        } else {
            Err(MessageBusError::routing_error(
                route_id,
                "路由不存在",
            ))
        }
    }

    /// 添加默认过滤器
    pub fn add_default_filter(&mut self, filter: Box<dyn MessageFilter>) {
        self.default_filters.push(filter);
    }

    /// 路由消息，返回匹配的订阅者 ID 列表
    pub fn route_message(&self, message: &Message) -> Vec<String> {
        let mut matched_subscribers = Vec::new();

        // 首先检查默认过滤器
        if !self.default_filters.iter().all(|f| f.matches(message)) {
            return matched_subscribers;
        }

        // 检查每个路由规则
        for route in self.routes.values() {
            // 检查主题是否匹配
            if route.pattern.matches(message.topic()) {
                // 检查所有过滤器是否匹配
                if route.filters.iter().all(|f| f.matches(message)) {
                    matched_subscribers.extend(route.subscriber_ids.clone());
                }
            }
        }

        matched_subscribers
    }

    /// 检查消息是否被任何路由匹配
    pub fn matches_any_route(&self, message: &Message) -> bool {
        !self.route_message(message).is_empty()
    }

    /// 获取所有路由 ID
    pub fn get_route_ids(&self) -> Vec<String> {
        self.routes.keys().cloned().collect()
    }

    /// 获取路由的订阅者数量
    pub fn get_route_subscriber_count(&self, route_id: &str) -> usize {
        self.routes
            .get(route_id)
            .map(|route| route.subscriber_ids.len())
            .unwrap_or(0)
    }

    /// 清空所有路由
    pub fn clear(&mut self) {
        self.routes.clear();
        self.default_filters.clear();
    }
}

impl Default for MessageRouter {
    fn default() -> Self {
        Self::new()
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::message::Message;
    use serde_json::json;

    #[test]
    fn test_topic_pattern_exact() {
        let pattern = TopicPattern::exact("user.events.login");
        assert!(pattern.matches("user.events.login"));
        assert!(!pattern.matches("user.events.logout"));
    }

    #[test]
    fn test_topic_pattern_wildcard() {
        let pattern = TopicPattern::wildcard("user.events.*");
        assert!(pattern.matches("user.events.login"));
        assert!(pattern.matches("user.events.logout"));
        assert!(!pattern.matches("user.profile.update"));

        let pattern = TopicPattern::wildcard("user.**");
        assert!(pattern.matches("user.events.login"));
        assert!(pattern.matches("user.profile.update"));
        assert!(pattern.matches("user.settings.theme.change"));
        assert!(!pattern.matches("admin.events.login"));
    }

    #[test]
    fn test_topic_pattern_regex() {
        let pattern = TopicPattern::regex(r"user\.(events|profile)\..*").unwrap();
        assert!(pattern.matches("user.events.login"));
        assert!(pattern.matches("user.profile.update"));
        assert!(!pattern.matches("user.settings.change"));
    }

    #[test]
    fn test_content_filter() {
        let message = Message::new(
            "user.events.login",
            json!({"user_id": 123, "action": "login", "ip": "192.168.1.1"})
        );

        let filter = ContentFilter::equal("user_id", json!(123));
        assert!(filter.matches(&message));

        let filter = ContentFilter::equal("user_id", json!(456));
        assert!(!filter.matches(&message));

        let filter = ContentFilter::contains("ip", "192.168");
        assert!(filter.matches(&message));
    }

    #[test]
    fn test_composite_filter() {
        let message = Message::new(
            "user.events.login",
            json!({"user_id": 123, "action": "login", "level": 1})
        );

        let filter1 = Box::new(ContentFilter::equal("user_id", json!(123)));
        let filter2 = Box::new(ContentFilter::equal("action", json!("login")));

        let and_filter = CompositeFilter::and(vec![filter1, filter2]);
        assert!(and_filter.matches(&message));

        let filter1 = Box::new(ContentFilter::equal("user_id", json!(456)));
        let filter2 = Box::new(ContentFilter::equal("action", json!("login")));

        let or_filter = CompositeFilter::or(vec![filter1, filter2]);
        assert!(or_filter.matches(&message));
    }

    #[test]
    fn test_message_router() {
        let mut router = MessageRouter::new();

        // 添加路由规则
        let pattern = TopicPattern::wildcard("user.events.*");
        let filter = Box::new(ContentFilter::equal("level", json!(1)));
        router.add_route("user_events", pattern, vec![filter]);

        // 添加订阅者
        router.add_subscriber_to_route("user_events", "subscriber1").unwrap();
        router.add_subscriber_to_route("user_events", "subscriber2").unwrap();

        // 测试消息路由
        let message = Message::new(
            "user.events.login",
            json!({"user_id": 123, "level": 1})
        );

        let matched = router.route_message(&message);
        assert_eq!(matched.len(), 2);
        assert!(matched.contains(&"subscriber1".to_string()));
        assert!(matched.contains(&"subscriber2".to_string()));

        // 测试不匹配的消息
        let message = Message::new(
            "user.events.login",
            json!({"user_id": 123, "level": 2})
        );

        let matched = router.route_message(&message);
        assert_eq!(matched.len(), 0);
    }
}